#include <webx/route.h>

class SendMail : public webx::ProcessBase
{
protected:
	int process();
};

HTTP_WEBAPP(SendMail)

int SendMail::process()
{
	static string queuename = stdx::format("%s:sendmail_queue", GetCurrentUser());

	param_string(flag);
	param_string(mail);

	if (flag == "C") return simpleResponse(Sharemem().open(queuename) ? XG_OK : XG_NOTFOUND);

	stdx::tolower(mail);

	auto sendMail = [&](const string& id, const string& msg){
		int res;
		MsgQueue mq;

		if (msg.length() > 0 && mq.open(queuename) && mq.push(msg.c_str(), msg.length()))
		{
			LogTrace(eINF, "send mail[%s] success[%d]", id.c_str(), res = msg.length());
		}
		else
		{
			LogTrace(eERR, "send mail[%s] failed[%d]", id.c_str(), res = mq.canUse() ? XG_SYSBUSY : XG_SYSERR);
		}

		return res;
	};
	
	int res = XG_PARAMERR;
	int timeout = 10 * 60;

	if (flag == "R" || flag == "P" || flag == "L" || flag == "T")
	{
		string id = app->getSequence();
		string sid = webx::GetSessionId(request);

		if (flag == "T")
		{
			checkSession(sid);
			checkSystemRight();

			param_string(title);
			param_string(content);
			param_string(grouplist);

			if (title.empty() || content.empty() || title.length() > 128 || content.length() > 1024 * 1024) return simpleResponse(XG_PARAMERR);

			JsonElement data;

			data["id"] = id;
			data["user"] = mail;
			data["title"] = title;
			data["content"] = content;
			data["grouplist"] = grouplist;

			res = sendMail(id, data.toString());
		}
		else if (webx::IsMailString(mail))
		{
			int times = 0;
			time_t now = time(NULL);
			const char* filepath = "res/etc/login.json";

			if (flag == "P") filepath = "res/etc/password.json";
			if (flag == "R") filepath = "res/etc/register.json";
			
			SmartBuffer temp;
			CgiMapData cfg = app->getCgiMapData(filepath);

			if (cfg.url.empty() || app->getFileContent(cfg.url, temp) <= 0)
			{
				LogTrace(eERR, "json file[%s] not found", filepath);

				return simpleResponse(XG_SYSERR);
			}

			try
			{
				checkSession(sid);

				long utime = stdx::atol(token->getExtdata("utime").c_str());

				if (utime + 60 > now) return simpleResponse(XG_AUTHFAIL);
	
				times = stdx::atoi(token->getExtdata("times").c_str());

				if (++times > 10) return simpleResponse(XG_AUTHFAIL);
			}
			catch(Exception e)
			{
				if (webx::GetSession(mail)) return simpleResponse(XG_AUTHFAIL);

				token = LoginToken::Create(timeout);
			}

			string sqlcmd = "SELECT USER FROM T_XG_USER WHERE MAIL=?";

			res = webx::GetDBConnect()->select(sqlcmd, sqlcmd, mail); 

			if (res == 0)
			{
				if (flag == "P")
				{
					LogTrace(eIMP, "mail[%s] not registered", mail.c_str());

					res = XG_NOTFOUND;
				}
			}
			else if (res > 0)
			{
				if (flag == "R")
				{
					LogTrace(eIMP, "mail[%s] registered", mail.c_str());

					res = XG_DUPLICATE;
				}
			}

			if (res >= 0)
			{
				string msg;
				string code;
				string link;
				string content;
				JsonElement data(JsonElement(temp.str()));
				const string& format = data.asString("content");

				if (format.empty())
				{
					LogTrace(eERR, "parse json file[%s] failed", cfg.url.c_str());
					
					return simpleResponse(XG_DATAERR);
				}

				stdx::format(code, "%06d", (int)((clock() + rand()) % 1000000));

				if (flag == "P" || flag == "R")
				{
					link = webx::GetParameter("WEBSITE");
				}
				else
				{
					char buffer[4096] = {0};
					string text = HEXEncode(mail.c_str(), mail.length(), buffer);

					link = webx::GetParameter("WEBSITE") + "/index?session=" + text + "&code=" + code;
				}

				stdx::format(content, format.c_str(), code.c_str(), timeout / 60, link.c_str());

				data["id"] = id;
				data["user"] = mail;
				data["content"] = content;
				data["deadline"] = (long)(now + timeout);

				if ((res = sendMail(id, data.toString())) < 0) return simpleResponse(res);

				token->setMail(mail);
				token->setExtdata("code", code);

				webx::GetSession(mail, 60);
				webx::SetSessionId(response, token->getSessionId());
			}

			token->setExtdata("times", stdx::str(times));
			token->setExtdata("utime", stdx::str(now));
			token->update();
		}
	}

	json["code"] = res;
	out << json;
	
	return XG_OK;
}